import processing.serial.*;

import oscP5.*;
import netP5.*;


PFont _myHelvetica;
PFont _myEidetic;


boolean _myIsPaused = false;

PrinterThread _myPrinterThread;
PImage targetImage;
PImage equalizeImage;
PImage ditherImage;
PImage captureImage;

OscP5 oscP5;
void setup(){
  size(600,500);
  oscP5 = new OscP5(this,7000);
  oscP5.plug(this,"capture","/capture");


  _myHelvetica = loadFont("HelveticaNeue-Bold-24.vlw");

  _myEidetic = loadFont("EideticNeo-Italic-18.vlw");
  targetImage = new PImage(160,160);
  ditherImage = new PImage(160,160);
  equalizeImage = new PImage(160,160);



  Serial thePort = new Serial(this, Serial.list()[0], 19200);
  println(Serial.list());

  _myPrinterThread = new PrinterThread(thePort, ditherImage); 

}




public void capture(int theX, int theY, int theRadius, String theFile) {
  println("### plug event method. received a message /capture.");
  println("received: "+theX+", "+theY+", "+theRadius+", "+theFile); 



  if(!_myPrinterThread.isBusy() && !_myIsPaused) {
    captureImage = loadImage(theFile); 
    targetImage.copy(captureImage, theX-theRadius, theY-theRadius, theRadius*2, theRadius*2, 0, 0, 160, 160);
    equalizeImage();
    ditherImage();
    _myPrinterThread.startPrint();

  }

}

void draw(){
  background(50,40,30);
  fill(255);
  noStroke();
  textFont(_myHelvetica);
  text("ICSY TK 5000",40,40);
  textFont(_myEidetic);
  text("mission control 0.1 alpha", 220, 40);
  text("last image",40,90);

  if(targetImage != null) image(targetImage, 40, 100);
  if(equalizeImage != null) image(equalizeImage, 220, 100);
  if(ditherImage != null) image(ditherImage, 400, 100);
  text("progress",40,290);

  rect(40,300,_myPrinterThread.getProgress() * (width-80), 20);

  text("status",40,350);
  textFont(_myHelvetica);
  if(_myIsPaused){
  text("PAUSED",40,370);
  }



}

void equalizeImage(){
  targetImage.loadPixels();
   equalizeImage.loadPixels();
   int cmin = 255;
   int cmax = 0;
  
  for (int x=0;x<targetImage.width;x++) {
    for (int y=0;y<targetImage.height;y++) {
      int c = (int)red(targetImage.get(x,y));
      cmin = min(cmin, c);
            cmax = max(cmax, c);
    }
    
  }
  
    for (int x=0;x<targetImage.width;x++) {
    for (int y=0;y<targetImage.height;y++) {
      int c =  (int)map(red(targetImage.get(x,y)), cmin, cmax, 0, 255);
      equalizeImage.set(x,y,color(c));
    }
    
  }
  equalizeImage.updatePixels();
  

}

void ditherImage(){
  ditherImage.loadPixels();
  
  int n = 4;
  float f=255./(pow(2,2*n)+1);
  for (int x=0;x<equalizeImage.width;x++) {
    for (int y=0;y<equalizeImage.height;y++) {
      color c=equalizeImage.get(x,y);
      float t=(n>0?dizza(x,y,n)*f:128);
      if (n==5) {        
      } 
      else {
        c=color(t>=(red(c)+green(c)+blue(c))/3.?0:255);
      }
      ditherImage.set(x,y,c);
    }
  }
  
    ditherImage.updatePixels();

}




void keyPressed(){
  if(key == 'p') _myIsPaused = !_myIsPaused;
}

int dizza(int i, int j, int n) {
  if (n==1) {
    return (i%2!=j%2 ? 2 : 0) + j%2;
  }
  else{
    return 4*dizza(i%2, j%2, n-1) + dizza(int(i/2), int(j/2), n-1);
  }
}

